"""
订单相关API - 集成WebSocket推送
"""
import uuid
from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, status, Request
from sqlalchemy.orm import Session
from starlette.concurrency import run_in_threadpool
from typing import List, Optional

from utils.database import get_db
from utils import JWTUtils
from Models.travel.models import Order, Attraction
from Models.travel.schemas import AttractionInfo
from Views.home.websocket.ws_notifier import (
    notify_order_status_change,
    notify_payment_success,
    notify_payment_failed
)
from pydantic import BaseModel

router = APIRouter(prefix="/travel/orders", tags=["订单管理"])


def get_current_user_id(request: Request) -> int:
    """从请求头获取当前用户ID"""
    authorization = request.headers.get("Authorization")
    if not authorization:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="未提供认证令牌"
        )
    
    token = authorization.replace("Bearer ", "").strip()
    payload = JWTUtils.decode_access_token(token)
    if not payload or not payload.get("user_id"):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="认证令牌无效"
        )
    return payload["user_id"]


class OrderCreate(BaseModel):
    """创建订单请求"""
    attraction_id: int
    quantity: int = 1
    contact_name: str
    contact_phone: str
    notes: Optional[str] = None


class OrderInfo(BaseModel):
    """订单信息"""
    id: int
    order_no: str
    user_id: int
    attraction_id: int
    attraction_name: Optional[str] = None
    quantity: int
    unit_price: float
    total_amount: float
    status: str
    contact_name: Optional[str] = None
    contact_phone: Optional[str] = None
    notes: Optional[str] = None
    created_at: datetime
    updated_at: datetime
    paid_at: Optional[datetime] = None
    
    class Config:
        from_attributes = True


class OrderListResponse(BaseModel):
    """订单列表响应"""
    total: int
    page: int
    page_size: int
    orders: List[OrderInfo] = []


@router.post("", response_model=OrderInfo, summary="创建订单")
async def create_order(
    order_data: OrderCreate,
    request: Request,
    db: Session = Depends(get_db)
):
    """创建订单"""
    user_id = get_current_user_id(request)
    
    def _create_order():
        # 检查景点是否存在
        attraction = db.query(Attraction).filter(
            Attraction.id == order_data.attraction_id,
            Attraction.is_active == True
        ).first()
        
        if not attraction:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="景点不存在"
            )
        
        # 生成订单号（使用统一的订单号生成工具）
        from utils.payment_utils import PaymentUtils
        order_no = PaymentUtils.generate_order_no(user_id)
        
        # 计算金额
        unit_price = attraction.price
        total_amount = unit_price * order_data.quantity
        
        # 验证金额和数量
        if order_data.quantity <= 0:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="购买数量必须大于0"
            )
        
        if unit_price <= 0:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="商品价格无效，无法创建订单"
            )
        
        if total_amount <= 0:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=f"订单总金额必须大于0（单价：{unit_price}，数量：{order_data.quantity}）"
            )
        
        # 创建订单
        order = Order(
            order_no=order_no,
            user_id=user_id,
            attraction_id=order_data.attraction_id,
            quantity=order_data.quantity,
            unit_price=unit_price,
            total_amount=total_amount,
            status="pending",
            contact_name=order_data.contact_name,
            contact_phone=order_data.contact_phone,
            notes=order_data.notes
        )
        
        db.add(order)
        db.commit()
        db.refresh(order)
        
        return order, attraction
    
    order, attraction = await run_in_threadpool(_create_order)
    
    # 发送订单创建通知
    notify_order_status_change(
        user_id=user_id,
        order_id=order.id,
        order_no=order.order_no,
        old_status="",
        new_status="pending",
        amount=order.total_amount
    )
    
    # 构造返回数据
    order_info = OrderInfo.model_validate(order)
    order_info.attraction_name = attraction.name
    return order_info


@router.get("", response_model=OrderListResponse, summary="获取订单列表")
async def get_orders(
    page: int = 1,
    page_size: int = 10,
    status: str = None,
    request: Request = None,
    db: Session = Depends(get_db)
):
    """获取当前用户的订单列表"""
    user_id = get_current_user_id(request)
    
    def _get_orders():
        query = db.query(Order).filter(Order.user_id == user_id)
        
        if status:
            query = query.filter(Order.status == status)
        
        total = query.count()
        orders = query.order_by(Order.created_at.desc()).offset(
            (page - 1) * page_size
        ).limit(page_size).all()
        
        # 加载景点信息
        for order in orders:
            if order.attraction:
                order.attraction_name = order.attraction.name
        
        return total, orders
    
    total, orders = await run_in_threadpool(_get_orders)
    
    return OrderListResponse(
        total=total,
        page=page,
        page_size=page_size,
        orders=[OrderInfo.model_validate(o) for o in orders]
    )


@router.get("/{order_id}", response_model=OrderInfo, summary="获取订单详情")
async def get_order_detail(
    order_id: int,
    request: Request,
    db: Session = Depends(get_db)
):
    """获取订单详情"""
    user_id = get_current_user_id(request)
    
    def _get_order():
        order = db.query(Order).filter(
            Order.id == order_id,
            Order.user_id == user_id
        ).first()
        
        if not order:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="订单不存在"
            )
        
        if order.attraction:
            order.attraction_name = order.attraction.name
        
        return order
    
    order = await run_in_threadpool(_get_order)
    return OrderInfo.model_validate(order)




@router.post("/{order_id}/cancel", summary="取消订单")
async def cancel_order(
    order_id: int,
    request: Request,
    db: Session = Depends(get_db)
):
    """取消订单"""
    user_id = get_current_user_id(request)
    
    def _cancel_order():
        order = db.query(Order).filter(
            Order.id == order_id,
            Order.user_id == user_id
        ).first()
        
        if not order:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="订单不存在"
            )
        
        if order.status not in ["pending", "paid"]:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=f"订单状态为 {order.status}，无法取消"
            )
        
        old_status = order.status
        order.status = "cancelled"
        db.commit()
        db.refresh(order)
        
        return order, old_status
    
    order, old_status = await run_in_threadpool(_cancel_order)
    
    # 发送订单状态变化通知
    notify_order_status_change(
        user_id=user_id,
        order_id=order.id,
        order_no=order.order_no,
        old_status=old_status,
        new_status="cancelled",
        amount=order.total_amount
    )
    
    return {"message": "订单已取消", "order_id": order.id, "status": order.status}

